13
תגובות
אולי הכותרת לא ברורה, התכוונתי למשהו כזה:
2 | 4; // 6
something(6) \\ array(2, 4)

אני מחזיר שגיאה כמספר שהוא חזקה של 2.
0 - אין שגיאה.
1 - שגיאה a.
2 - שגיאה b.
4 - שגיאה c.
8 - שגיאה d.

אם לדוגמה התרחשו גם שגיאה b וגם שגיאה c אני מחזיר 6 (שזה 2 + 4, הסכום של השגיאות).
לחבר את שהגיאות ולהחזיר זו לא הבעיה.
אני מחפש דרך יעילה להפריד את השגיאות, אם לדוגמה זה 6, אז לקבל 2 ו-4. אם זה 11, לקבל 1, 2 ו-8.
אני יכול להשתמש בלולאה אבל חיפשתי אולי משהו יותר מובנה בשפה, כמו איזו פונקציה או אולי שילוב של כמה אופרטורים בינאריים כדי לקבל את התוצאה.

תודה מראש.

13 תשובות

avatar ענה iiddaannyy ב 27 ליוני 2012 #

כמובן שכל זה בהנחה ששגיאה לא יכולה להתרחש יותר מפעם אחת, אחרת זה לא אפשרי מבחינה מתמטית.

avatar ענה iiddaannyy ב 27 ליוני 2012 #

למי שלא הבין, הנה פונקציה שכתבתי שמבצעת את זה:

function elements($n) {
  $elements = array();
  for ($i = strlen($n = (string)base_convert($n, 10, 2)) - 1, $j = 0; $i >= 0; $i--, $j++) {
    if ($n[$i]) {
      $elements[] = (int)base_convert(pow(10, $j), 2, 10);
    }
  }
  return $elements;
}

הפלט של זה:
var_dump(elements(11), elements(6), elements(19));

הוא זה:
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(8)
}
array(2) {
  [0]=>
  int(2)
  [1]=>
  int(4)
}
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(16)
}

אפשר לראות שזה מוצא את הגורמים שהם חזקות של 2. השאלה היא האם יש משהו מובנה בשפה שיעבוד מהר יותר.

avatar ענה intval ב 27 ליוני 2012 #

יעזור יותר להבין אם תסביר שוב ובמילים אחרות מה צריך לקבל, כמה דוגמאות לפלט קלט ומה לא עובד בקוד שלך

avatar ענה intval ב 27 ליוני 2012 #

מאוד יכול להיות שאתה לא צריך להפריד שום דבר בכלל וסתם כמה תנאים יספיקו לך:

<?php

const A = 1;
const B = 2;
const C = 4;
const D = 8;

$someValue = 12;

if( $someValue & A) echo 'its a A', '<br/>';
if( $someValue & B) echo 'its a B', '<br/>';
if( $someValue & C) echo 'its a C', '<br/>';
if( $someValue & D) echo 'its a D', '<br/>';

avatar ענה iiddaannyy ב 27 ליוני 2012 #

נתתי שלוש דוגמאות לפלט ולקלט, בהודעה השניה שלי.
הקוד שלי עובד, אני פשוט רוצה לדעת האם קיים משהו זהה מובנה בשפה.

בנוגע לתגובה השנייה שלך, זה טוב אם אני רוצה לדעת האם שגיאה מסוימת קרתה.
מה שאני רוצה זה "לחלץ" את השגיאות שהתרחשו.

avatar ענה intval ב 27 ליוני 2012 #

תכניס את התנאים מהתגובה השניה שלי לתוך לולאה שבה תבדוק את כל השגיאות האפשריות האם הם התרחשו

avatar ענה iiddaannyy ב 27 ליוני 2012 #

אני לא תמיד יודע מהן כל השגיאות האפשריות.
במסד מוצמדת כל שגיאה (במילים) אל המספר שלה.
ככה שלחלץ את השגיאות זו הדרך היחידה, השאלה היא האם יש דרך לחלץ את השגיאות בצורה טובה יותר.

avatar ענה intval ב 27 ליוני 2012 #

חוץ מלעבור בלולאה על כל החזקות של שתיים? לא חושב.
למה אתה בכלל מחבר אותם ביחד? למה שהפונקציה שלך לא תחזיר מערך של מספרי שגיאות ולא את הביטים שלהן ?

avatar ענה iiddaannyy ב 27 ליוני 2012 #

לא צריך לעבור עם לולאה על כל החזקות של 2, זה סתם בזבוז. תראה את הקוד שלי.

ואני באמת אחזיר מערך. סתם מיותר להתעסק עם זה כשלא צריך.

avatar ענה intval ב 27 ליוני 2012 #

בדיוק אותה לולאה, רק שבמקום מספרים אתה עובר על מחרוזות, שזה רעיון קצת יותר גרוע.. מבחינת כמות מעברי הלולאה הם זהים, מבחינת הפעולות שצריך לעשות בתוך הלולאה - המעברים למחרוזת והשוואת מחרוזות נראים לי קצת מיותרים.

avatar ענה iiddaannyy ב 27 ליוני 2012 #

אני לא עובד על כל החזקות של 2.
אני רץ על הספרות של המספר.

לדוגמה 11 שמיוצג בבסיס בינארי על ידי 1011.
מתחיל מספרת האחדות, היא 1? כן. j כרגע הוא 0. 10 בחזקת 0 זה 1, נמיר לעשרוני מבינארי, נשאר 1, מוסיפים למערך.
ספרת העשרות - 1. j הוא 1 כרגע. 10 בחזקת 1 זה 10, נמיר מבינארי לעשרוני, נקבל 2. מוסיפים 2 למערך.
ספרת המאות - 0. j הוא כרגע 2.
ספרת האלפים - 1. j הוא כרגע 3. 10 בחזקת 3 זה 1000, נמיר לעשרוני, נקבל 8. נוסיף למערך 8.

ככה קיבלנו 1, 2, 8. פשוט רצים על הספרות, בודקים מה "דלוק" (1), ממירים אותו לעשרוני ומוסיפים למערך.

ככה שהלולאה רצה n פעמים, כש-n זה מספר הספרות של הקלט.

avatar ענה intval ב 27 ליוני 2012 #

הבנתי את הקוד שלך :)
במקרה הגרוע - בדיוק אותו n תהיה כמות הפעמים שיהיה עליך להכפיל משהו ב 2 כדי לקבל את החזקה הבאה שלה.

function elements($n)
{
  $result = [];
  $pow = 0.5;

  while( $n >= ( $pow *= 2 ) )
    if($n & $pow)
      $result[] = $pow;

  return $result;
}

print_r(elements(517));

avatar ענה iiddaannyy ב 27 ליוני 2012 #

הייתי בטוח שריצה על החזקות של 2 יהיה פחות מהיר -.-
שלך מהיר יותר (פי 7-8) וגם עובד במספרים גדולים (שלי לא בגלל base_convert).

;)